/** @jsxImportSource @emotion/react */
import {  css } from "@emotion/react";
import * as React from "react";
import {
    useTheme, TwoHalfFrame, Text,
    Navbar,
    Toolbar,
    DdMenuItem,
    VerticalMenu, Stack, StackItem, useMMenuBarOcup,
} from "customize-easy-ui-component";

//import { useSession,  useSignOut } from "../auth";
import { Link as RouterLink } from "../src/routing/Link";
//import { Link as RouterLink, useRoute, useLocation, Switch, Route } from "wouter";
//import { TaskList } from "./task/TaskList";
//import { DeviceList } from "./DeviceList";
//import { useCountOfTask } from "./db";
import {UserContext} from "../src/routing/UserContext";
import useLogoutMutation from "../src/common/useLogoutMutation";
import {useCallback, useContext} from "react";
import RoutingContext from "../src/routing/RoutingContext";
import {PreloadedQuery, usePreloadedQuery, useRefetchableFragment} from "react-relay/hooks";
import { OneRequestMainQuery } from "../src/request/__generated__/OneRequestMainQuery.graphql";
//import { DeviceList } from "./DeviceList";
//import {TaskList} from "../task/TaskList";
//import {useParams, useRouteMatch} from "react-router";
//找不到类型定义！ @types/babel-plugin-relay 没提供TS支持
//import {graphql} from 'relay-runtime';  //实际数据可以发起并获得到，可惜babel报错，纯粹不允许？
//import { match, } from 'path-to-regexp';
import {OneRequestMain$key} from "../src/request/__generated__/OneRequestMain.graphql";
// import {TwoHalfFrame} from "../../UiDebugSave/sample/TwoHalfFrame";

import {getReportModelTypes} from "../src/inspect/report/reportTypeMap";
// import {css} from "@emotion/react";
// import {businessTypeMap} from "../device/edit/CommnBase";
// import {AgreementBoundDevices} from "./AgreementBoundDevices";
import {requestStatusMap} from "../src/request/RequestList";
import {OneRequestMainQuery$data} from "../src/request/__generated__/OneRequestMainQuery.graphql";
import {RefetchFnDynamic} from "react-relay/relay-hooks/useRefetchableFragmentNode";
import useBuildRequestMutation from "../src/request/hook/useBuildRequestMutation";

const graphql = require("babel-plugin-relay/macro");    //编译器解析graphql文本代码。


/**更为通用的HOOK Relay查询。
 * 依赖类型 OneAgreementMainQuery是和文件名字有关的。 OneAgreementMainProps是路由器Main页面组件通用的类型接口。
 * 规定参数有 props.prepared.query, $modId:ID! 都是来自路由器发起的查询,
 * 通用输出 data,
 * 复用组件正常代码复用 #应该是采用agreement,而不是采用data,的输出。
 * 提前获取数据的复用代码做法和正常的Relay片段放在儿子组件的两个模式实际上可以共同交叉使用。
 * 这里必须内省定义上pttype，左边页面有用到该字段。
 * */
// export function useOneAgreement(props: OneAgreementMainProps)
// {
//     //【问题】要想复用组件每一个实际包容引入的页面能够用useFragment(来接收数据的就只能在这里都要分别的为每一个实际页面单独定义片段...ViewMain声明的。否则不能用Ref$Key来接收数据，只能提前强制声明数据类型接收后传递给下级组件。
//     //既然是代码复用：干脆改成这里明确定义内省字段，而不是...OneAgreementWraper这样的片段声明形式，直接提取data，提前但是data的数据类型也就提前约束和确定死了，后续复用代码必须按照这里约束类型来引用数据data，就失去Relay自由片段特性。
//     //缺点就是：不能像正常Relay应该用的useFragment( OneAgreementMainQuery$data;)来到最终子组件来接收数据。只能提前层层传递已经data提取的有特定类型约束的数据对象了，和普通Relay相比有点怪。
//
//
//     //【注意】代码复用，只能是强类型的agreement对象只好事先就声明字段Relay不能事后才声明内省字段的，上面的graphql`必须就地声称字段不能用片段形式...ViewMain的。
//     return {
//         agreement,
//         refetch,     //这样组件props多传递参数模式：就能支持复用代码都能支持refetch不用多个地方都需定义useRefetchableFragment()。
//         //【鱼和熊掌】若返回这个 data, 然后走正常的Relay片段在儿子组件接收模式的，就没必要去传递refetch,参数的。缺点就是不能通用复用，需要每一个都要声明定能够以声明片段。
//         agreement0,
//     };
// }


interface OneRequestMainProps {
    prepared: {
        query: PreloadedQuery<OneRequestMainQuery>;
    }
    children: React.ReactNode;
    id?: string;
    routeData: any;
}
/**协议申请单的左半边内容：有点奇怪，右半边是主题主体内容，左半边是辅助的列表附属显示，这里有点怪异。#左半边通常是列表和上一级导航父辈页面内容。
* */
export default function OneRequestMain(props: OneRequestMainProps) {
  const theme = useTheme();
  //const {user} = useSession();
    const {user, setUser} =useContext(UserContext);
  // const isLarge = useMedia({ minWidth: "768px" });
 // const qs = queryString.parse(window.location.search);
 //  const {filter:devfl, } =React.useContext(DevfilterContext);
 // const [, params] = useRoute("/device/:recipe*");
    const { isExact }=props.routeData;      //二级路由层次，下面没有分支路由
    const {history } = useContext(RoutingContext);
    let rightLayerKey =history.location.pathname;
    /*let { taskId } = useParams<any>(); let match = useRouteMatch("/task/:slug")全部无法使用，自定义路由Context没对上。
    //折腾获取路由taskId参数,不见得都有。
    const matchpath = match("/task/:taskId/isp/:ispId", { decode: decodeURIComponent });
    var mparams= matchpath(history.location.pathname);
    let paaas= mparams&& mparams.params;
    let seeTaskId=(paaas as any)['taskId'];
    */

  // const [activeTab, setActiveTab] = React.useState(0);
  // const renderList = isLarge || isExact;  　//大屏或者小屏但是没有显示具体明细页的场合就显示列表组件。
   //为何这一行执行好多边？幸亏子组件不会执行多边。
  console.log("TaskMain金准history",props.routeData.params.taskId,"props.routeData",props.routeData,"rightLayerKey:",rightLayerKey);
  const { call:signOut } = useLogoutMutation();
    // const {agreement, refetch} = useOneAgreement(props);

    const data = usePreloadedQuery<OneRequestMainQuery>(
        graphql`
            query OneRequestMainQuery(
                $modId:ID!,
            ) {
                node(id: $modId){
                    id, __typename,
                    ... on Request {
                        id,status,ispu{id,name}
                        auditor{id,person{id,name}}
                        crman{id,person{id,name}}
                    }
                }
                ...OneRequestMain
            }
        `,
        props.prepared.query,
    );
    const { node:agreement0, }=data;     //通常接收方式
    //useRefetchableFragment用法特别必须首先上usePreloadedQuery之后嵌套儿子组件或者顺序上跟着的Hook: #实际上 输出数据类型被下面替换掉了！
    //直接跟随：可是通常应该放入儿子组件当中的。
    const [datanode, refetch] = useRefetchableFragment(
        graphql`
            fragment OneRequestMain on Query
            @refetchable(queryName: "OneRequestMainRefetchQuery") {
                node(id: $modId)
                {
                    id, __typename,
                    ... on Request {
                        id,status,ispu{id,name}
                        auditor{id,person{id,name}}
                        crman{id,person{id,name}},
                        mdtime, mod,
                    }
                }
            }
        `,
        data as OneRequestMain$key,
    );
    //上面的data必须再次声明类型的 as OneAgreementMain$key,。依赖于Relay编译器生成代码。
    //为了支持refetch引进： 必须再一次接收数据datanode。
    //上面的"OneAgreementMainRefetchQuery")必须直接声明devs{}若使用...AgreementBoundDevices来声明的很可能无法提取出来devs,复用缺点@必须一致的提前声称字段。
    const { node:agreement, }=datanode;


    if(!agreement)  return <RouterLink href="/"><Text variant="h3">找不到该通用申请单,回首页</Text></RouterLink>;

    //右半边页面来自路由器的注入props.children；另外必须有的左边的列表页面。
  return (
          <TwoHalfFrame rightPanel={agreement && props.children} >
              <OneRequestWraper agreement={agreement} refetch={refetch}/>
          </TwoHalfFrame>
  );
};


interface OneRequestWraperProps {
    //这个类型不能乱来，TS编译要用，底下的data要看这个: 返回graphql模型字段定义了吗;
    //正常REF模式是  modref: OneAgreementWraper$key;
    agreement: OneRequestMainQuery$data["node"];
    //只能这样声明 泛型的 类型了：
    refetch: RefetchFnDynamic<any, any>;
}
/**申请单左边的列表区域。
 * */
const OneRequestWraper: React.FunctionComponent<OneRequestWraperProps>
    = ({agreement, refetch}) => {
    //第一次啊运行吗？
    const mountedRef = React.useRef(0);
    if(!mountedRef.current) {
        mountedRef.current = 1;
    }
    else
        mountedRef.current++;
    //后面refetch:实际是 (vars: TVars, options?: TOptions) => Disposable;的回调函数。
    // const [data, refetch] = useRefetchableFragment(
    //     graphql`
    //         fragment OneAgreementWraper on Query
    //         @refetchable(queryName: "OneAgreementWraperRefetchQuery") {
    //             node(id: $modId)
    //             {
    //                 id, __typename,
    //                 ... on Agreement {
    //                     id,ptno,status,servu{id,name}
    //                     dispatcher{id,dep{id,name},office{id,name}},complDate,aux
    //                     ...AgreementBoundDevices
    //                 }
    //             }
    //         }
    //     `,
    //     props.modref,
    // );
    console.log("来OneRequestWraper看当前的data=",agreement );
    // const agreement= props.agreement;
    // @ts-ignore
    const details = agreement?.detail_list?.edges?.map(edge => edge?.node);
    const typicisp = details && details.length>0 && details[0]?.isp;         //典型Isp
    const {user} = useContext(UserContext);
    const  aux = JSON.parse('{}');        //特别处理 依赖反转。
    const theme = useTheme();
    //提取生成关联的数据Task-Detail[0]-Isp-Report-stm-author[]；检验员人员初始化依据第一个Isp设备的主报告而定。做个短路ApprovalStm快捷访问。
    const [query, ] = React.useState("");
    //const [relation, setRelation] = React.useState();

    const [, setFilter] = React.useState({where:
            {cod:query },
    });

    const noUsers = !query && !agreement;
    //下层沉下去的 setIndex切换显示界面；
    const [index, setIndex] = React.useState(0);


    /*
    const { submit:dispatch2liablFunc, } = useDispatchToLiabler({
        task: relation, liabler: 1
    });
    //发后端verify:{id:1,username:'herzhang'},后端实体User(String name){}会直接构造输入参数，把{id=1, username=herzhang}当成name构造User
    const { submit:dispatch2TaskFunc, } = useDispatchTaskTo({
        task: relation,date:'2021-02-09', verify:1, ispmen:[21,1,16]
    });
    */
    const {call:deleteRequestFunc,doing,called, result}= useBuildRequestMutation();
    // const {call:dispatch2TaskFunc,doing:doing2 }= useDispatchTaskToMutation();
    // const {call:cancelTaskFunc,doing:canceling, called, reset}= useCancellationTaskMutation();
    const { history } = useContext(RoutingContext);

    // const {call:summaryTaskFeeFunc,doing:summing,called:summed, result:summrs}= useSummaryTaskFeeMutation();
    // const {call:finishTaskFunc, }= useFinishTaskMutation();


    React.useEffect(() => {
        //console.log("伪善setQueryResul02=" ,query,usersFind);
        let filtercomp={where:
                {cod:query },
            offset:0,
            first:5,
            orderBy: "useDt",
            asc: false
        };
        setFilter(filtercomp);
    }, [query]);
    //这两个useEffect的前后顺序不能颠倒，顺序非常重要，后面的依赖于前面的useEffect更新结果。
    //usersFind=搜索框搜到到的user;
    /*切换到Stack的第一层*/
    // useEffect(() => {
    //     if(!canceling && called) {
    //         console.log("取消后端有了应答！-taskId=");
    //         //同步化处理机制，等待后端真正应答了，才能更新页面，否则继续等待。
    //         //setRelation(undefined);
    //         setIndex(0);
    //         reset();    //setCalled=false,导致不会再次运行上面这段;
    //     }
    //    //return () => dispose();
    // }, [canceling, called,reset]);

    //三个命令各自的配置模态对话框显示？
    // const [diaLiab, setDiaLiab] = React.useState(false);
    // const [master, setMaster] = React.useState<any>(agreement?.typicstm?.master);         //就是报告校核人
    // const [ispMens, setIspMens] = React.useState<any>(agreement?.typicstm?.authr);         //多个 检验人员[User];
    // const [reviewer, setReviewer] = React.useState<any>(agreement?.typicstm?.reviewer);    //审核人
    // const [approver, setApprover] = React.useState<any>(agreement?.typicstm?.approver);    //审批人
    const [modeltype, setModeltype] = React.useState<any>( 'EL-DJ' );
    const [modelversion, setModelversion] = React.useState<any>( '1' );
    // const [taskDate, setTaskDate] = React.useState<any>(agreement?.date);

    // const {menu: officeItem, dialog: officeDlg}= useOfficeDialogMenu(task! as TaskLikeData);
    // const {menu: liablerItem, dialog: liablerDlg}= useLiablerDialogMenu(task! as TaskLikeData);
    //一个任务底下#多个设备 单一次检验 设备种类典型的品种？ 可能有多种报告模板类型啊？？不能非常确定！全部依照典型设备来做，后面可改。
    //会有多次的render经过这里，每一回都会要求执行里面的计算啊， 【提高性能考虑】改成useMemo保存;
    const models =React.useMemo(() => getReportModelTypes('41','413','','REGUL',true), []);
    //上面这个副作用必须 加usersFind，否则无法继续处理后端数据带来的必要的UI反馈变化。
    const {barHeight } = useMMenuBarOcup(history.routeData?.isExact);
    //控件<Stack 是堆叠式的，像导航条；适用同一个模板显示只需上级给下级参数调整的场景。根据上一叠页面选择触发状态relation给下一叠参数来控制下一级显示；更多嵌套很困难。
    // if(canceling)
    //     return (
    //         <div style={{
    //                 display: "flex",
    //                 height: '87vh'
    //             }}
    //         >
    //           <Spinner doing={canceling} css={{margin: 'auto'}}/>
    //         </div>
    //     );
    //   console.log("点击触发 为何出2回:diaLiab=",diaLiab);
    //对话框和点击弹出遭遇可能要延迟 onPress= setTimeout(() => { setDisplayDialog(true); }, 0)避免点透点穿 自动关闭;
    //底下：禁止显示導航條disableNav； 只能是固定值navHeight，是依赖父辈的<Stack>传递context给儿孙<StackTitle>
    //这里<Stack  只有一层的，还没有标题工具条：实际等于摆设。
    //多套上一层DIV增加独立控制布局的能力； margin: auto;简易的遭遇小尺度内容的可屏幕居中显示。
    return (
        <React.Fragment>
            <div css={{
                margin: 'auto',
                background: 'white',
            }}>
                <div
                    css={{
                        width:'100%',
                    }}
                >
                    <Navbar  position="sticky"
                             css={{
                                 backgroundColor: "white",
                             }}
                    >
                        <Toolbar
                            css={{
                                alignItems: "center",
                                display: "flex",
                                minHeight: `${barHeight}`,
                                [theme.mediaQueries.lg]: {
                                    minHeight: `${barHeight}`,
                                }
                            }}
                        >
                            <Text
                                css={{
                                    flex: 1,
                                    textAlign: "center",
                                    [theme.mediaQueries.md]: {
                                        textAlign: "left"
                                    }
                                }}
                                wrap={false}
                                variant="h5"
                                gutter={false}
                            >
                                {` `}
                            </Text>
                            <VerticalMenu>
                                <DdMenuItem label="刷新本协议" onPress={() => refetch({first:4,},
                                    {fetchPolicy: "network-only"})}
                                />
                                <DdMenuItem label="生成协议附属任务"
                                            onPress={() => {
                                                // history.push("/agreement/"+agreement?.id+'/'+agreement?.pttype+'/addTask');
                                            }} />
                                <DdMenuItem label="删除本协议" onPress={() => {
                                    //删除协议前提：要取消全部任务@；刚刚取消任务就点击已关联任务页面报错: 【后端缓存原因】导致不同步的短期报错。
                                    deleteRequestFunc(agreement?.id!, 'DEL',{});
                                }} />
                            </VerticalMenu>
                        </Toolbar>
                    </Navbar>
                    <div css={{ marginLeft:'0.5rem', marginTop:'1rem',
                        backgroundColor: agreement?.status==='DONE'? 'pink': 'transparent',
                    }}>
                        <Text variant="h6">{`${requestStatusMap.get(agreement?.status!) || '新'}`} </Text>
                        <Text variant="h6">申请创建者：{agreement?.crman?.person?.name || '$'}</Text>
                        <Text variant="h6">{aux?.服务内容}</Text>
                        <Text variant="h6">关联的设备如下：</Text>
                        { '未知申请单类型'}
                    </div>
                </div>

                <Stack
                    navStyle={css({ position: 'sticky',  top: 0,})}
                    style={{
                        overflow: 'unset'
                    }}
                    index={index} disableNav={true} navHeight={40}
                    onIndexChange={i => setIndex(i)}
                    items={[
                        {
                            content: (
                                <StackItem className="ItemConte"
                                           css={{
                                               // marginBottom: `${barHeight}`,
                                           }}
                                           style={{ position: undefined, boxShadow:undefined }}
                                >
                                    <div className="DlistInnerF1"
                                         css={{overflowY: "auto", height: "100%",}}
                                    >
{/*                                        {agreement && (
                                            <AgreementBoundDevices key={agreement?.id} task={agreement!} id={agreement?.id!} />
                                        )}*/}
                                    </div>
                                </StackItem>
                            )
                        }
                    ]}/>
            </div>

        </React.Fragment>
    );
};
